﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Treely.Data.Model.Abstract;

namespace Treely.Data.Model
{
    public class AdditionQuestion : MathAnswerable, IAnswerable
    {
        public List<int> Addends { get; set; }

        public void Generate(AnswerType answerType, int minimumAddend, int maximumAddend, int numberOfAddends, int numberOfAnswerChoices = 0)
        {
            Subject = QuestionSubject.Addition;
            Addends = new List<int>();
            AnswerType = answerType;
            for (var i = 0; i < Math.Max(2, numberOfAddends); i++)
            {
                Addends.Add(RandomNumber.Next(minimumAddend, maximumAddend));
            }
            Addends = Addends.OrderByDescending(x => x).ToList();
            CorrectAnswer = Addends.Sum();

            if (AnswerType == AnswerType.MultipleChoice)
            {
                int falseAnswer = CorrectAnswer;
                if (numberOfAnswerChoices == 0) numberOfAnswerChoices = 2;
                NumericAnswers = new List<int>() { CorrectAnswer };
                for (var j = 0; j < numberOfAnswerChoices; j++)
                {
                    while (NumericAnswers.Any(x => x.Equals(falseAnswer)))
                    {
                        falseAnswer = RandomNumber.Next(minimumAddend, maximumAddend) * Addends.Count;
                    }
                    NumericAnswers.Add(falseAnswer);
                }
            }
        }

        public AdditionQuestion(AnswerType answerType, int minimumAddend, int maximumAddend, int numberOfAddends,
            int numberOfAnswerChoices = 0)
        {
            RandomNumber = new Random();
            Generate(answerType, minimumAddend, maximumAddend, numberOfAddends, numberOfAnswerChoices);
        }

        public AdditionQuestion(DifficultyLevel level, Random random)
        {
            RandomNumber = random;
            switch (level)
            {
                case DifficultyLevel.None:
                case DifficultyLevel.Preschool:
                    Generate(AnswerType.MultipleChoice, 0, 3, 1, 2);
                    return;

                case DifficultyLevel.Kindergarten:
                    Generate(AnswerType.MultipleChoice, 0, 5, 1, 2);
                    return;

                case DifficultyLevel.FirstGrade:
                    Generate(AnswerType.MultipleChoice, 1, 10, 1, 4);
                    return;

                case DifficultyLevel.SecondGrade:
                    Generate(AnswerType.Text, 0, 12, 1);
                    return;

                case DifficultyLevel.ThirdGrade:
                    if (RandomNumber.Next(0, 100) > 50)
                        Generate(AnswerType.Text, 10, 100, 1);
                    else Generate(AnswerType.Text, 5, 50, 2);
                    return;

                default:
                    Generate(AnswerType.Text, 100, 400, 2);
                    return;
            }
        }

        public override string ToString()
        {
            return Addends
                .Select(x => x.ToString())
                .Aggregate((x, y) => x.ToString() + " + " + y.ToString() + " = ?");
        }

        public override string ToStringVertical()
        {
            return base.ToStringVertical('+', Addends);
        }
    }
}